package com.management.demo.service.impl;

import com.management.demo.service.MinIOService;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class MinIOServiceImpl implements MinIOService {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.expiry}")
    private Integer expiry;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${minio.bucket-name}")
    private String bucketName;

    @Override
    public void createBucket(String bucketName) throws Exception {
        if (!bucketExists(bucketName)) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    @Override
    public void uploadFile(String bucketName, String objectName, MultipartFile file) throws Exception {
        InputStream inputStream = file.getInputStream();
        String contentType = file.getContentType();

        minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
                .stream(inputStream, inputStream.available(), -1).contentType(contentType).build());
    }

    @Override
    public InputStream downloadFile(String bucketName, String objectName) throws Exception {
        return minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucketName).object(objectName).build());
    }

    @Override
    public void deleteFile(String bucketName, String objectName) throws Exception {
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(bucketName).object(objectName).build());
    }

    @Override
    public String getObjectUrl(String bucketName, String objectName, int expiry) throws Exception {
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(Method.GET).bucket(bucketName).object(objectName).expiry(expiry).build());
    }

    @Override
    public String getObjectUrl(String objectName) throws Exception {
        String url = stringRedisTemplate.opsForValue().get("minio:" + bucketName + ":" + objectName);
        if (StringUtils.isBlank(url)) {
            url = getObjectUrl(bucketName, objectName, expiry);
            stringRedisTemplate.opsForValue().set("minio:" + bucketName + ":" + objectName, url, expiry, TimeUnit.SECONDS);
        }
        return url;
    }

    @Override
    public List<Bucket> listBuckets() throws Exception {
        return minioClient.listBuckets();
    }

    @Override
    public boolean bucketExists(String bucketName) throws Exception {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }
}
